package com.icode.web.startup.security.filter;

import com.icode.web.startup.security.MyAuthenticationToken;
import com.icode.web.startup.security.exception.CaptchaAuthenticationException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.ServletRequestBindingException;
import org.springframework.web.bind.ServletRequestUtils;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Collection;

/**
 * User: alexz
 * Date: 2015/9/24
 * Time: 14:19
 */
public class MyFormAuthenticationProcessingFilter extends UsernamePasswordAuthenticationFilter {
    private String verifyCodeName = "verifyCode";
    private boolean ignoreCase = true;

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
//        String code = obtainVerifyCode(request);
//
//        String actualCode = (String) request.getSession().getAttribute(verifyCodeName);
//
//        if (StringUtils.isEmpty(code)) {
//            throw new CaptchaAuthenticationException("no code exists in the request.");
//        }
//
//        if (StringUtils.isEmpty(actualCode)) {
//            throw new CaptchaAuthenticationException("no code exists in the session.");
//        }
//
//        if (ignoreCase) {
//            if (code.equalsIgnoreCase(actualCode)) {
//                return super.attemptAuthentication(request, response);
//            }
//        } else {
//            if (code.equals(actualCode)) {
//                return super.attemptAuthentication(request, response);
//            }
//        }
        return super.attemptAuthentication(request, response);
//        throw new CaptchaAuthenticationException("the code exists in the request is not equal to the code exists in the session");
    }

    @Override
    protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authResult) throws IOException, ServletException {
        super.successfulAuthentication(request, response, chain, authResult);
        Object principal = authResult.getPrincipal();
        Object credentials = authResult.getCredentials();
        Collection<? extends GrantedAuthority> authorities = authResult.getAuthorities();
        Object details = authResult.getDetails();
        MyAuthenticationToken myAuthenticationToken = new MyAuthenticationToken(principal, credentials, authorities);
        myAuthenticationToken.setDetails(details);
        SecurityContextHolder.getContext().setAuthentication(myAuthenticationToken);
    }

    private String obtainVerifyCode(HttpServletRequest request) {
        try {
            return ServletRequestUtils.getRequiredStringParameter(request, verifyCodeName);
        } catch (ServletRequestBindingException e) {
            throw new CaptchaAuthenticationException("It's wrong to obtain verify code.");
        }
    }

    public void setVerifyCodeName(String verifyCodeName) {
        Assert.hasText(verifyCodeName, "Captcha parameter must not be empty or null");
        this.verifyCodeName = verifyCodeName;
    }

    public void setIgnoreCase(boolean ignoreCase) {
        this.ignoreCase = ignoreCase;
    }
}
